from app.users.models import User
from app.users.models_help import update_user
from common import security
from common.db import engine
from datetime import timedelta
from fastapi.security import OAuth2PasswordBearer
from fastapi import Depends, HTTPException
from pydantic import BaseModel
from jwt.exceptions import InvalidTokenError
from pydantic import ValidationError
from sqlmodel import Session
from starlette import status
from typing import Any, Generator, Annotated



def parse_cors(v: Any) -> list[str] | str:
    if isinstance(v, str) and not v.startswith("["):
        return [i.strip() for i in v.split(",")]
    elif isinstance(v, list | str):
        return v
    raise ValueError(v)


class ResponseDatas(BaseModel):
    status_code: int = status.HTTP_200_OK
    data: Any = dict()  # 使用字典类型注解，并提供默认值
    message: str = "success"

    # 可选：添加一个类方法方便创建实例
    @classmethod
    def create(cls, data: Any, message: str = 'success', status_code: int = status.HTTP_200_OK):
        return cls(
            status_code=status_code,
            data=data,
            message=message
        )


def response_data(data, status_code=status.HTTP_200_OK, message='success') -> ResponseDatas:
    return ResponseDatas.create(
        data=data,
        status_code=status_code,
        message=message
    )


def get_db() -> Generator[Session, None, None]:
    with Session(engine) as session:
        yield session


SessionDep = Annotated[Session, Depends(get_db)]

reusable_oauth2 = OAuth2PasswordBearer(tokenUrl=f"/users/login")

TokenDep = Annotated[str, Depends(reusable_oauth2)]


# 创建token
def create_token(user: User):
    # 60 minutes * 24 hours * 1 day  = 1 days
    access_token_expire_minutes = 60 * 24 * 8
    access_token_expires = timedelta(minutes=access_token_expire_minutes)
    return security.create_access_token(user.id, expires_delta=access_token_expires)  # 生成token


# token 验证并获取用户
def get_current_user(session: SessionDep, token: TokenDep) -> type[User]:
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        payload = security.get_token_payload(token)  # token 解析
        user_id: str = payload.get("sub")
        if user_id is None:
            raise credentials_exception
    except (InvalidTokenError, ValidationError):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Could not validate credentials",
        )
    user = session.get(User, user_id)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    if not user.is_active:
        user = update_user(session, user=user, is_active=True)
    return user


CurrentUser = Annotated[User, Depends(get_current_user)]
